extern "C"
{
#include "ncp_log.h"
}
#include "ncp_rule.h"
#include "../../include/NMMediator.h"
#include "../tinyxml/tinyxml.h"
#include "../TaskScheduler.h"
#include "../util.h"
#include "../logger.h"

/* globle static rule vector */
static def_rule_list g_rule_list;
static def_stat_list g_stat_list;
extern CRITICAL_SECTION critical_rule;

bool rule_insert_rule(char* md5, char* str_xml)
{
	if ((md5 == NULL) || (str_xml == NULL)) return false;

	def_rule* rule = new def_rule;		
	if(NULL == rule) return false;

	TiXmlDocument xml;	
	xml.Parse(str_xml);
	TiXmlElement* rootElem = xml.FirstChildElement("ruleprops");

	if ( rootElem )
	{
		rule->node    = grammar_create_tree(const_cast<char*>(rootElem->FirstChildElement("syntax")->GetText()));
		if(NULL == rule->node) goto __ERROR__;

		rule->enabled = strcmp(CHK_NULL_S(rootElem->FirstChildElement("enabled")->GetText()), "true") == 0;
		rule->desc    = CHK_NULL_S(rootElem->FirstChildElement("desc")->GetText());
		rule->timeout = STR2INT(rootElem->FirstChildElement("timeout")->GetText());

		TiXmlElement* commandElem = rootElem->FirstChildElement("command");
		if ( commandElem )
		{
			rule->lock   = CHK_NULL_S(commandElem->FirstChildElement("lock")->GetText());
			rule->unlock = CHK_NULL_S(commandElem->FirstChildElement("unlock")->GetText());
		}

		rule->md5 = md5;
		EnterCriticalSection(&critical_rule);
		g_rule_list.push_back(rule);
		LeaveCriticalSection(&critical_rule);
		return true;
	}

__ERROR__:
	delete rule;
	return false;
}
bool rule_delete_rule(char* md5)
{
	def_rule_list::iterator ite_rule;	
    
    for(ite_rule=g_rule_list.begin(); ite_rule!=g_rule_list.end(); ++ite_rule)
	{
		if(0 == strcmp((*ite_rule)->md5.c_str(), md5))
		{
			grammar_free_tree((*ite_rule)->node);	
			delete (*ite_rule);
			g_rule_list.erase(ite_rule);			
			return true;
		}
    }

	return false;
}
bool rule_insert_stat(char* md5, char* syntex)
{
	if ((md5 == NULL) || (syntex == NULL)) return false;

	def_stat* stat = new def_stat;		
	if(NULL == stat)
	{
		return false;
	}

	stat->node           = grammar_create_tree(syntex);
	if(NULL == stat->node)
	{
		delete stat;
		return false;
	}

	string str_md5       = md5;
	stat->count          = 0;	
	g_stat_list[str_md5] = stat;
	return true;
}
bool rule_delete_stat(char* md5)
{
	EnterCriticalSection(&critical_rule);
	string str_md5 = md5;
	def_stat_list::iterator iter = g_stat_list.find(str_md5);	
	LeaveCriticalSection(&critical_rule);

	if(g_stat_list.end() != iter)
	{
		grammar_free_tree(iter->second->node);
		delete iter->second;
		g_stat_list.erase(iter);
		return true;
	}
	else
	{
		return false;
	}	
}


/*create rule vector*/
bool rule_create_vector()
{
	int i           = 0;
	int ruleCount   = 0;
	char **markList = NULL;	

#if LOG_LEVEL_THR >= LOG_CUR_LEVEL
	fprintf(g_log_io, LOG_RULE_START);
#endif

	g_rule_list.clear();	
	markList = NM_getRuleList(SELECT_FROM_TABLE(RuleTable), &ruleCount);	

	for (i=0; i<ruleCount; i++)
	{
#if LOG_LEVEL_THR >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_RULE_PARSE, i);
#endif
		TiXmlDocument xml;
		char *xmlProps = NM_getRuleProps(markList[i]);		
		xml.Parse(xmlProps);
		NM_free(xmlProps);
		TiXmlElement* rootElem = xml.FirstChildElement("ruleprops");

		if ( rootElem )
		{
			def_rule* rule = new def_rule;		
			if(NULL == rule)
			{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
			fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
				break;
			}

			rule->node    = grammar_create_tree(const_cast<char*>(rootElem->FirstChildElement("syntax")->GetText()));			
			if(NULL == rule->node)
			{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
				fprintf(g_log_io, LOG_RULE_PARSE_ERROR, i);
#endif
				delete rule;
				continue;
			}

			rule->md5 = markList[i];
			rule->enabled = strcmp(CHK_NULL_S(rootElem->FirstChildElement("enabled")->GetText()), "true") == 0;
			rule->desc    = CHK_NULL_S(rootElem->FirstChildElement("desc")->GetText());
			rule->timeout = STR2INT(rootElem->FirstChildElement("timeout")->GetText());
			TiXmlElement* commandElem = rootElem->FirstChildElement("command");
			if ( commandElem )
			{
				rule->lock   = CHK_NULL_S(commandElem->FirstChildElement("lock")->GetText());
				rule->unlock = CHK_NULL_S(commandElem->FirstChildElement("unlock")->GetText());
			}

			g_rule_list.push_back(rule);
		}

#if LOG_LEVEL_FOR>= LOG_CUR_LEVEL
		grammar_draw_tree(rule->node);
#endif
	}

	NM_freeList(markList, ruleCount);

//////////////////////////////////////////////////////////////////////////////////////
//  Stats 
//////////////////////////////////////////////////////////////////////////////////////
#if LOG_LEVEL_THR >= LOG_CUR_LEVEL
	fprintf(g_log_io, LOG_STAT_START);
#endif

	g_stat_list.clear();	
	markList = NM_getStatsList(SELECT_FROM_TABLE(StatsTable), &ruleCount);	

	for (i=0; i<ruleCount; i++)
	{
#if LOG_LEVEL_THR >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_STAT_PARSE, i);
#endif
		
		def_stat* stat = new def_stat;		
		if(NULL == stat)
		{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
			fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
			break;
		}

		stat->node           = grammar_create_tree(NM_getStatsProps(markList[i]));
		if(NULL == stat->node)
		{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
			fprintf(g_log_io, LOG_STAT_PARSE_ERROR, i);
#endif
			delete stat;
			continue;
		}

		string str_md5       = markList[i];
		g_stat_list[str_md5] = stat;
		stat->count          = 0;
#if LOG_LEVEL_FOR>= LOG_CUR_LEVEL
		grammar_draw_tree(stat->node);
#endif
	}

	NM_freeList(markList, ruleCount);
	return true;
}

/*free rule vector*/
bool rule_free_vector()
{	
    def_rule_list::iterator ite_rule;
    
    for(ite_rule=g_rule_list.begin(); ite_rule!=g_rule_list.end(); ++ite_rule)
	{
        grammar_free_tree((*ite_rule)->node);	
		delete (*ite_rule);
    }

	g_rule_list.clear();
	
	def_stat_list::iterator ite_stat;
    
    for(ite_stat=g_stat_list.begin(); ite_stat!=g_stat_list.end(); ++ite_stat)
	{
		def_stat* stat = ite_stat->second;
        grammar_free_tree(stat->node);	
		delete (stat);
    }
	
	g_stat_list.clear();
	
	return true;
}

/* static global packet struct */
static def_packet_struct* g_packet_struct = NULL;

/* macro */
void rule_macro_replace(string& str, def_packet_struct* packet_struct, RuleIPPacket *pPacket)
{
	if (NULL == packet_struct) return;

	string::size_type pos_s = string::npos;
	string::size_type pos_e = string::npos;
	char buf[32];

	/** SRC MAC */
	sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\0",
		packet_struct->ether_header.saddr.char1,
		packet_struct->ether_header.saddr.char2,
		packet_struct->ether_header.saddr.char3,
		packet_struct->ether_header.saddr.char4,
		packet_struct->ether_header.saddr.char5,
		packet_struct->ether_header.saddr.char6);
	if (pPacket != NULL) strcpy(pPacket->src.mac, buf);
	if (!str.empty()) {
		pos_s = str.find("${SRCMAC}");
		pos_e = strlen("${SRCMAC}");
		if(string::npos != pos_s)
		{
			str.replace(pos_s, pos_e, buf);
		}
	}

	/** DES MAC */
	sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\0",
		packet_struct->ether_header.daddr.char1,
		packet_struct->ether_header.daddr.char2,
		packet_struct->ether_header.daddr.char3,
		packet_struct->ether_header.daddr.char4,
		packet_struct->ether_header.daddr.char5,
		packet_struct->ether_header.daddr.char6);
	if (pPacket != NULL) strcpy(pPacket->des.mac, buf);
	if (!str.empty()) {
		pos_s = str.find("${DESMAC}");
		pos_e = strlen("${DESMAC}");
		if(string::npos != pos_s)
		{
			str.replace(pos_s, pos_e, buf);
		}
	}

	if (packet_struct->ether_header.type != ETHERTYPE_IP) return;

/********************************************************\ 
 *	Following just only handle IP packet.
 *	pPacket->type = packet_struct->ip_header.proto;
\********************************************************/
	pPacket->type = packet_struct->ip_header.proto;
	/** SRC IP */
	sprintf(buf, "%d.%d.%d.%d\0",
		packet_struct->ip_header.saddr.char1,
		packet_struct->ip_header.saddr.char2,
		packet_struct->ip_header.saddr.char3,
		packet_struct->ip_header.saddr.char4);
	if (pPacket != NULL) strcpy(pPacket->src.ip, buf);
	if (!str.empty()) {
		pos_s = str.find("${SRCIP}");
		pos_e = strlen("${SRCIP}");
		if(string::npos != pos_s)
		{
			str.replace(pos_s, pos_e, buf);
		}
	}

	/** DES IP */
	sprintf(buf, "%d.%d.%d.%d\0",
		packet_struct->ip_header.daddr.char1,
		packet_struct->ip_header.daddr.char2,
		packet_struct->ip_header.daddr.char3,
		packet_struct->ip_header.daddr.char4);
	if (pPacket != NULL) strcpy(pPacket->des.ip, buf);
	if (!str.empty()) {
		pos_s = str.find("${DESIP}");
		pos_e = strlen("${DESIP}");
		if(string::npos != pos_s)
		{
			str.replace(pos_s, pos_e, buf);
		}
	}

	/** SRC PORT */
	if (packet_struct->ip_header.proto == IPPROTO_TCP) {
		sprintf(buf, "%d\0", packet_struct->tcp_header.src_port);
		if (pPacket != NULL) pPacket->src.port = packet_struct->tcp_header.src_port;
	}
	else if (packet_struct->ip_header.proto == IPPROTO_UDP) {
		sprintf(buf, "%d\0", packet_struct->udp_header.src_port);
		if (pPacket != NULL) pPacket->src.port = packet_struct->udp_header.src_port;
	}
	else {
		sprintf(buf, "%d\0", 0);
	}
	if (!str.empty()) {
		pos_s = str.find("${SRCPORT}");
		pos_e = strlen("${SRCPORT}");
		if(string::npos != pos_s)
		{
			str.replace(pos_s, pos_e, buf);
		}
	}

	/** DES PORT */
	if (packet_struct->ip_header.proto == IPPROTO_TCP) {
		sprintf(buf, "%d\0", packet_struct->tcp_header.des_port);
		if (pPacket != NULL) pPacket->des.port = packet_struct->tcp_header.des_port;
	}
	else if (packet_struct->ip_header.proto == IPPROTO_UDP) {
		sprintf(buf, "%d\0", packet_struct->udp_header.des_port);
		if (pPacket != NULL) pPacket->des.port = packet_struct->udp_header.des_port;
	}
	else {
		sprintf(buf, "%d\0", 0);
	}
	if (!str.empty()) {
		pos_s = str.find("${DESPORT}");
		pos_e = strlen("${DESPORT}");
		if(string::npos != pos_s)
		{
			str.replace(pos_s, pos_e, buf);
		}
	}
}

/* match rule */
bool rule_match(def_packet_struct* packet_struct)
{
	g_packet_struct = packet_struct;
	int i           = 0;

	EnterCriticalSection(&critical_rule);
    def_rule_list temp_rule_list = g_rule_list;
	LeaveCriticalSection(&critical_rule);
	def_rule_list::iterator iterator;
    
    for(iterator=temp_rule_list.begin(); iterator!=temp_rule_list.end(); ++iterator,++i)
	{
#if LOG_LEVEL_FIV >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_MATCH_RULE, i);
#endif
        
		if(grammar_excute_tree((*iterator)->node))
		{
#if LOG_LEVEL_FIV >= LOG_CUR_LEVEL
			fprintf(g_log_io, LOG_MATCH_RULE_TRUE);
#endif

			string lock   = (*iterator)->lock;
			RuleIPPacket packet;
			memset(&packet, 0, sizeof(RuleIPPacket));
			rule_macro_replace(lock, packet_struct, &packet);
			if(NULL != fireLoggerEventCallbak)
			{
				EventObject paramObj;
				paramObj.comefrom = 1;
				paramObj.md5Mark  = (*iterator)->md5.c_str();
				paramObj.desc     = (*iterator)->desc.c_str();
				paramObj.packet   = packet;
				fireLoggerEventCallbak( paramObj );
			}

			if (lock.empty()) {
				NM_WARN("rule_mach, string lock is empty\n");
				continue;
			}
			
			char md5AndIPMark[256];
			sprintf(md5AndIPMark, "%s|%d|%s-%s-%d|%s-%s-%d\0", 
				(*iterator)->md5.c_str(), packet.type,
				packet.src.mac, packet.src.ip, packet.src.port,
				packet.des.mac, packet.des.ip, packet.des.port);
			if ( taskSchedulerObject.hasItem(md5AndIPMark) ) continue;

			NM_sendCommandToDevice(auto_command_protocol, lock.c_str());
			if ( ((*iterator)->timeout > 0) && (!(*iterator)->unlock.empty()) ) {
				string unlock = (*iterator)->unlock;
				rule_macro_replace(unlock, packet_struct, NULL);

				TaskPropsMeta *pTaskProps = new TaskPropsMeta();
				pTaskProps->specified = 0;
				pTaskProps->frequency = 1;
				pTaskProps->interval  = (*iterator)->timeout;
				pTaskProps->desc.append( (*iterator)->desc.c_str() );
				pTaskProps->commandString.append( unlock.c_str() );	
				taskSchedulerObject.addScheduler( md5AndIPMark, pTaskProps );
			}
		}
#if LOG_LEVEL_FIV >= LOG_CUR_LEVEL
		else
		{
			fprintf(g_log_io, LOG_MATCH_RULE_FALSE);
		}
#endif
    }	
	
	EnterCriticalSection(&critical_rule);
    def_stat_list temp_stat_list = g_stat_list;
	LeaveCriticalSection(&critical_rule);
	def_stat_list::iterator ite_stat;
	def_stat*               stat = NULL;
    
    for(ite_stat=temp_stat_list.begin(), i=0; ite_stat!=temp_stat_list.end(); ++ite_stat,++i)
	{
#if LOG_LEVEL_FIV >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_MATCH_STAT, i);
#endif

		stat = ite_stat->second;
        
		if(grammar_excute_tree(stat->node))
		{
#if LOG_LEVEL_FIV >= LOG_CUR_LEVEL
			fprintf(g_log_io, LOG_MATCH_STAT_TRUE);
#endif

			EnterCriticalSection(&critical_rule);
//			temp_stat_list[ite_stat->first]->count++;
			temp_stat_list[ite_stat->first]->count += 
				packet_struct->packet_data_len;
			LeaveCriticalSection(&critical_rule);
			
#if LOG_LEVEL_FIV >= LOG_CUR_LEVEL
			fprintf(g_log_io, LOG_MATCH_STAT_COUNT, stat->count);
#endif
		}
#if LOG_LEVEL_FIV >= LOG_CUR_LEVEL
		else
		{
			fprintf(g_log_io, LOG_MATCH_STAT_FALSE);
		}
#endif
    }	
	return true;
}

unsigned long rule_stat_count(char* md5)
{
	if(NULL == md5)
	{
		return NULL;
	}

	string str_md5                   = md5;
	def_stat_list::iterator ite_stat = g_stat_list.find(str_md5);

	return  (ite_stat != g_stat_list.end()) ? ite_stat->second->count : 0;	
}

/*===================================================================*/
/* deal                                                              */
/*===================================================================*/

def_bool op_ipaddr_equer(def_ipaddr* ipaddr_cap, def_ipaddr* ipaddr_filter);
def_bool op_ipaddr_area(def_ipaddr* ipaddr_cap, def_ipaddr* ipaddr_filter_from, def_ipaddr* ipaddr_filter_to);
def_bool op_macaddr_equer(def_macaddr* macaddr_cap, def_macaddr* macaddr_filter);
def_bool op_macaddr_area(def_macaddr* macaddr_cap, def_macaddr* macaddr_filter_from, def_macaddr* macaddr_filter_to);
def_bool op_number_equer(def_number number_cap, def_number number_filter);
def_bool op_number_area(def_number number_cap, def_number number_filter_from, def_number number_filter_to);
def_bool op_data_equer(def_net_data net_data, def_count offset, def_number number_filter);
def_bool op_data_area(def_net_data net_data, def_count offset_from, def_count offset_to, def_hex* hex_filter);

def_bool op_ipaddr_equer(def_ipaddr* ipaddr_cap, def_ipaddr* ipaddr_filter)
{
	if( ipaddr_cap->char1 == ipaddr_filter->char1 &&
		ipaddr_cap->char2 == ipaddr_filter->char2 &&
		ipaddr_cap->char3 == ipaddr_filter->char3 &&
		ipaddr_cap->char4 == ipaddr_filter->char4 )
	{
		return def_true;
	}
	else
	{
		return def_false;
	}
}

def_bool op_ipaddr_area(def_ipaddr* ipaddr_cap, def_ipaddr* ipaddr_filter_from, def_ipaddr* ipaddr_filter_to)
{
	if(ipaddr_filter_from->char1 < ipaddr_cap->char1 && ipaddr_cap->char1 < ipaddr_filter_to->char1)
	{
		return def_true;
	}
	if(ipaddr_filter_from->char1 > ipaddr_cap->char1 && ipaddr_cap->char1 > ipaddr_filter_to->char1)
	{
		return def_false;
	}

	if(ipaddr_filter_from->char2 < ipaddr_cap->char2 && ipaddr_cap->char2 < ipaddr_filter_to->char2)
	{
		return def_true;
	}
	if(ipaddr_filter_from->char2 > ipaddr_cap->char2 && ipaddr_cap->char2 > ipaddr_filter_to->char2)
	{
		return def_false;
	}

	if(ipaddr_filter_from->char3 < ipaddr_cap->char3 && ipaddr_cap->char3 < ipaddr_filter_to->char3)
	{
		return def_true;
	}
	if(ipaddr_filter_from->char3 > ipaddr_cap->char3 && ipaddr_cap->char3 > ipaddr_filter_to->char3)
	{
		return def_false;
	}

	if(ipaddr_filter_from->char4 < ipaddr_cap->char4 && ipaddr_cap->char4 < ipaddr_filter_to->char4)
	{
		return def_true;
	}
	if(ipaddr_filter_from->char4 > ipaddr_cap->char4 && ipaddr_cap->char4 > ipaddr_filter_to->char4)
	{
		return def_false;
	}

	return def_true;
}

def_bool op_macaddr_equer(def_macaddr* macaddr_cap, def_macaddr* macaddr_filter)
{
	if( macaddr_cap->char1 == macaddr_filter->char1 &&
		macaddr_cap->char2 == macaddr_filter->char2 &&
		macaddr_cap->char3 == macaddr_filter->char3 &&
		macaddr_cap->char4 == macaddr_filter->char4 &&
		macaddr_cap->char5 == macaddr_filter->char5 &&
		macaddr_cap->char6 == macaddr_filter->char6 )
	{
		return def_true;
	}
	else
	{
		return def_false;
	}
}

def_bool op_macaddr_area(def_macaddr* macaddr_cap, def_macaddr* macaddr_filter_from, def_macaddr* macaddr_filter_to)
{
	if(macaddr_filter_from->char1 < macaddr_cap->char1 && macaddr_cap->char1 < macaddr_filter_to->char1)
	{
		return def_true;
	}
	if(macaddr_filter_from->char1 > macaddr_cap->char1 && macaddr_cap->char1 > macaddr_filter_to->char1)
	{
		return def_false;
	}

	if(macaddr_filter_from->char2 < macaddr_cap->char2 && macaddr_cap->char2 < macaddr_filter_to->char2)
	{
		return def_true;
	}
	if(macaddr_filter_from->char2 > macaddr_cap->char2 && macaddr_cap->char2 > macaddr_filter_to->char2)
	{
		return def_false;
	}

	if(macaddr_filter_from->char3 < macaddr_cap->char3 && macaddr_cap->char3 < macaddr_filter_to->char3)
	{
		return def_true;
	}
	if(macaddr_filter_from->char3 > macaddr_cap->char3 && macaddr_cap->char3 > macaddr_filter_to->char3)
	{
		return def_false;
	}

	if(macaddr_filter_from->char4 < macaddr_cap->char4 && macaddr_cap->char4 < macaddr_filter_to->char4)
	{
		return def_true;
	}
	if(macaddr_filter_from->char4 > macaddr_cap->char4 && macaddr_cap->char4 > macaddr_filter_to->char4)
	{
		return def_false;
	}

	if(macaddr_filter_from->char5 < macaddr_cap->char5 && macaddr_cap->char5 < macaddr_filter_to->char5)
	{
		return def_true;
	}
	if(macaddr_filter_from->char5 > macaddr_cap->char5 && macaddr_cap->char5 > macaddr_filter_to->char5)
	{
		return def_false;
	}

	if(macaddr_filter_from->char6 < macaddr_cap->char6 && macaddr_cap->char6 < macaddr_filter_to->char6)
	{
		return def_true;
	}
	if(macaddr_filter_from->char6 > macaddr_cap->char6 && macaddr_cap->char6 > macaddr_filter_to->char6)
	{
		return def_false;
	}

	return def_true;
}

def_bool op_number_equer(def_number number_cap, def_number number_filter)
{
	return number_cap == number_filter;
}

def_bool op_number_area(def_number number_cap, def_number number_filter_from, def_number number_filter_to)
{
	return (number_filter_from <= number_cap) && (number_cap <=number_filter_to);
}

def_bool op_data_equer(def_net_data net_data, def_count offset, def_number number_filter)
{
	return net_data[offset] == number_filter;	
}

def_bool op_data_area(def_net_data net_data, def_count offset_from, def_count offset_to, def_hex* hex_filter)
{
	int i = 0;

	if(offset_to-offset_from+1 != hex_filter->count)
	{
		return def_false;
	}

	for(i=offset_from; i<=offset_to; i++)
	{
		if(net_data[i] != hex_filter->value[i-offset_from])
		{
			return def_false;
		}
	}

	return def_true;
}


/* deal function*/
def_bool grammar_deal_excute(def_operation_node* operation)
{
	if(NULL == operation || NULL == g_packet_struct)
	{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_NULL_POINTER_ERROR);
#endif
		return def_false;
	}

	switch(operation->operation_type)
	{
	case enum_operation_type_packet_data_byte:
		if(NULL == g_packet_struct->packet_data)
		{
			return def_false
		}

		if(g_packet_struct->packet_data_len <=  operation->operation_values[0]->node_value.value->value_value.number)
		{
			return def_false;
		}		

		return op_data_equer(g_packet_struct->packet_data, 
			operation->operation_values[0]->node_value.value->value_value.number,
			operation->operation_values[1]->node_value.value->value_value.number);		
		break;
	case enum_operation_type_packet_data_area:
		if(NULL == g_packet_struct->packet_data)
		{
			return def_false
		}

		if(g_packet_struct->packet_data_len <=  operation->operation_values[0]->node_value.value->value_value.number_area->number_to)
		{
			return def_false;
		}

		return op_data_area(g_packet_struct->packet_data,
			operation->operation_values[0]->node_value.value->value_value.number_area->number_from,
			operation->operation_values[0]->node_value.value->value_value.number_area->number_to,
			operation->operation_values[1]->node_value.value->value_value.hex);		
		break;
	case enum_operation_type_ip_src:
/*		if(NULL == g_packet_struct->ip_header)
		{
			return def_false;
		}
*/
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_ipaddr)
		{
			return op_ipaddr_equer(&g_packet_struct->ip_header.saddr, 
				operation->operation_values[0]->node_value.value->value_value.ipaddr);
		}
		else
		{
			return op_ipaddr_area(&g_packet_struct->ip_header.saddr, 
				&operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_from, 
				&operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_to);			
		}
		break;
	case enum_operation_type_ip_des:
/*		if(NULL == g_packet_struct->ip_header)
		{
			return def_false;
		}
*/
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_ipaddr)
		{
			return op_ipaddr_equer(&g_packet_struct->ip_header.daddr, 
				operation->operation_values[0]->node_value.value->value_value.ipaddr);
		}
		else
		{
			return op_ipaddr_area(&g_packet_struct->ip_header.daddr, 
				&operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_from, 
				&operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_to);			
		}
		break;
	case enum_operation_type_mac_src:
/*		if(NULL == g_packet_struct->ether_header)
		{
			return def_false;
		}
*/
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_macaddr)
		{
			return op_macaddr_equer(&g_packet_struct->ether_header.saddr, 
				operation->operation_values[0]->node_value.value->value_value.macaddr);			
		}
		else
		{
			return op_macaddr_area(&g_packet_struct->ether_header.saddr, 
				&operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from, 
				&operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to);			
		}
		break;
	case enum_operation_type_mac_des:
/*		if(NULL == g_packet_struct->ether_header)
		{
			return def_false;
		}
*/
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_macaddr)
		{
			return op_macaddr_equer(&g_packet_struct->ether_header.daddr, 
				operation->operation_values[0]->node_value.value->value_value.macaddr);			
		}
		else
		{
			return op_macaddr_area(&g_packet_struct->ether_header.daddr, 
				&operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from, 
				&operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to);			
		}
		break;
	case enum_operation_type_tcp_port_src:
/*		if(NULL == g_packet_struct->tcp_header)
		{
			return def_false;
		}
*/
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_number)
		{
			return op_number_equer(g_packet_struct->tcp_header.src_port, 
				operation->operation_values[0]->node_value.value->value_value.number);
		}
		else
		{
			return op_number_area(g_packet_struct->tcp_header.src_port,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_from,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_to);			
		}
		break;
	case enum_operation_type_tcp_port_des:
/*		if(NULL == g_packet_struct->tcp_header)
		{
			return def_false;
		}
*/
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_number)
		{
			return op_number_equer(g_packet_struct->tcp_header.des_port, 
				operation->operation_values[0]->node_value.value->value_value.number);
		}
		else
		{
			return op_number_area(g_packet_struct->tcp_header.des_port,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_from,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_to);			
		}
		break;
	case enum_operation_type_tcp_data_byte:
/*		if(NULL == g_packet_struct->tcp_header)
		{
			return def_false;
		}
*/
		if(NULL == g_packet_struct->tcp_data)
		{
			return def_false;
		}

		if(g_packet_struct->tcp_data_len <=  operation->operation_values[0]->node_value.value->value_value.number)
		{
			return def_false;
		}

		return op_data_equer(g_packet_struct->tcp_data, 
			operation->operation_values[0]->node_value.value->value_value.number,
			operation->operation_values[1]->node_value.value->value_value.number);		
		break;
	case enum_operation_type_tcp_data_area:
/*		if(NULL == g_packet_struct->tcp_header)
		{
			return def_false;
		}
*/
		if(NULL == g_packet_struct->tcp_data)
		{
			return def_false;
		}

		if(g_packet_struct->tcp_data_len <=  operation->operation_values[0]->node_value.value->value_value.number_area->number_to)
		{
			return def_false;
		}

		return op_data_area(g_packet_struct->tcp_data,
			operation->operation_values[0]->node_value.value->value_value.number_area->number_from,
			operation->operation_values[0]->node_value.value->value_value.number_area->number_to,
			operation->operation_values[1]->node_value.value->value_value.hex);
		break;
	case enum_operation_type_udp_port_src:
/*		if(NULL == g_packet_struct->udp_header)
		{
			return def_false;
		}
*/
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_number)
		{
			return op_number_equer(g_packet_struct->udp_header.src_port, 
				operation->operation_values[0]->node_value.value->value_value.number);
		}
		else
		{
			return op_number_area(g_packet_struct->udp_header.src_port,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_from,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_to);			
		}
		break;
	case enum_operation_type_udp_port_des:
/*		if(NULL == g_packet_struct->udp_header)
		{
			return def_false;
		}
*/
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_number)
		{
			return op_number_equer(g_packet_struct->udp_header.des_port, 
				operation->operation_values[0]->node_value.value->value_value.number);
		}
		else
		{
			return op_number_area(g_packet_struct->udp_header.des_port,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_from,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_to);			
		}
		break;
	case enum_operation_type_udp_data_byte:
/*		if(NULL == g_packet_struct->udp_header)
		{
			return def_false;
		}
*/
		if(NULL == g_packet_struct->udp_data)
		{
			return def_false
		}

		if(g_packet_struct->udp_data_len <=  operation->operation_values[0]->node_value.value->value_value.number)
		{
			return def_false;
		}		

		return op_data_equer(g_packet_struct->udp_data, 
			operation->operation_values[0]->node_value.value->value_value.number,
			operation->operation_values[1]->node_value.value->value_value.number);		
		break;
	case enum_operation_type_udp_data_area:
/*		if(NULL == g_packet_struct->udp_header)
		{
			return def_false;
		}
*/
		if(NULL == g_packet_struct->udp_data)
		{
			return def_false
		}

		if(g_packet_struct->udp_data_len <=  operation->operation_values[0]->node_value.value->value_value.number_area->number_to)
		{
			return def_false;
		}

		return op_data_area(g_packet_struct->udp_data,
			operation->operation_values[0]->node_value.value->value_value.number_area->number_from,
			operation->operation_values[0]->node_value.value->value_value.number_area->number_to,
			operation->operation_values[1]->node_value.value->value_value.hex);		
		break;
	default:
		return def_false;
	}	
}
